﻿<!DOCTYPE html>
<head>
    <meta charset="UTF-8">

    <script type="text/javascript">

        /* Description:
         * A minimal WebRTC peer that tests data channel connectivity.
         */

        const STUN_URL = "stun:stun.sipsorcery.com";
        const WEBSOCKET_URL = "ws://127.0.0.1:8081/";
        const DATA_CHANNEL_LABEL = "dc1";
        const RANDOM_BYTE_LENGTH = 10000;
        const HASH_INPUT_MAX_LEN = 65535;

        var dc, pc, ws;
        var isClosed = true;
        var makeOffer = false;

        async function start() {

            if (!isClosed) {
                await closePeer();
            }
            isClosed = false;

            pc = new RTCPeerConnection({ iceServers: [{ urls: STUN_URL }] });
            //pc = new RTCPeerConnection({ iceServers: [{ urls: 'turn:turn.sipsorcery.com', username: 'aaron', credential: 'password' }], iceTransportPolicy: "relay" });

            pc.onicecandidate = evt => {
                if (evt.candidate !== null) {
                    console.log(`ice candidate ${evt.candidate.candidate}`);
                    evt.candidate && ws.send(JSON.stringify(evt.candidate));
                }
            }

            // Diagnostics.
            pc.onicegatheringstatechange = () => console.log("onicegatheringstatechange: " + pc.iceGatheringState);
            pc.oniceconnectionstatechange = () => console.log("oniceconnectionstatechange: " + pc.iceConnectionState);
            pc.onsignalingstatechange = () => console.log("onsignalingstatechange: " + pc.signalingState);
            pc.onconnectionstatechange = () => console.log("onconnectionstatechange: " + pc.connectionState);

            pc.ondatachannel = (evt) => console.log(`ondatachannel new data channel created: id ${evt.channel.id}, label ${evt.channel.label}.`);

            dc = pc.createDataChannel(DATA_CHANNEL_LABEL);
            dc.onopen = (event) => console.log(`data channel onopen: id=${dc.id}, label ${dc.label}.`);
            dc.onclose = (event) => console.log(`data channel onclose: id=${dc.id}, label ${dc.label}.`);
            dc.onmessage = onDataChannelMessage;

            ws = new WebSocket(document.querySelector('#websockurl').value, []);
            ws.onopen = async function () {
                if (makeOffer) {
                    pc.setLocalDescription()
                        .then(() => ws.send(JSON.stringify(pc.localDescription)));
                }
            }
            ws.onmessage = async function (evt) {
                var obj = JSON.parse(evt.data);
                if (obj?.candidate) {
                    if (pc.remoteDescription !== null) {
                        console.log("got remote ice candidate: " + evt.data);
                        pc.addIceCandidate(obj);
                    }
                    else {
                        console.log("no remote sdp, ignoring remote ice candidate: " + evt.data);
                    }
                }
                else if (obj?.sdp) {
                    await pc.setRemoteDescription(new RTCSessionDescription(obj));
                    pc.createAnswer()
                        .then((answer) => pc.setLocalDescription(answer))
                        .then(() => ws.send(JSON.stringify(pc.localDescription)));
                }
            };
        };

        function onDataChannelMessage(evt) {
            console.log(`data channel onmessage: message type ${evt.type}, label ${evt.target.label}, data ${evt.data}.`);
            if (evt.data instanceof ArrayBuffer) {
                console.log(`binary data of length ${evt.data.byteLength}.`);
                evt.target.send(evt.data);
            }
        }

        function sendMessage(message) {
            console.log(`send message: ${message}.`);
            dc?.send(message);
        }

        async function closePeer() {
            isClosed = true;
            await dc?.close();
            await pc?.close();
            await ws?.close();
        };

    </script>
</head>
<body>
    <div>
        <input type="text" id="websockurl" size="40" />
        <button type="button" class="btn btn-success" onclick="start();">Open</button>
        <button type="button" class="btn btn-success" onclick="closePeer();">Close</button>
    </div>

    <div>
        <input type="text" id="message" value="hello world" />
        <button type="button" class="btn btn-success" onclick="sendMessage(document.querySelector('#message').value);">Send Message</button>
    </div>
</body>

<script>
    document.querySelector('#websockurl').value = WEBSOCKET_URL;
</script>
